#include "pwm_input.hpp"
#include "apm32a10x_eint.h"
#include "apm32a10x_misc.h"
#include "apm32a10x_gpio.h"
#include "apm32a10x_tmr.h"
#include "system.h"

#include "stdio.h"

/* EINT Pin PB10 */

enum PWMInput_status{
    PWM_IN_LOW,
    PWM_IN_HIGH
};

enum PWMInput_status __pwm_in_status = PWM_IN_LOW;
static unsigned long int __pwm_in_high_tick = 0;
static unsigned long int __pwm_in_low_tick = 0;
static double __pwm_in_duty = 0.0;
static double __pwm_in_period = 0;

/* PWM input use TMR3 PC6. */

bool PWMInput::init(void){

    GPIO_Config_T gpio_configuration;
    System_setPeripheralClockEnable(CLK_GPIOC,TRUE);
    System_setPeripheralClockEnable(CLK_AFIO,TRUE);
    System_setPeripheralClockEnable(CLK_TMR3,TRUE);

    gpio_configuration.pin = GPIO_PIN_6;
    gpio_configuration.mode = GPIO_MODE_IN_PD;
    gpio_configuration.speed = GPIO_SPEED_50MHz;
    GPIO_Config(GPIOC,&gpio_configuration);
    
    GPIO_ConfigPinRemap(GPIO_FULL_REMAP_TMR3);

    TMR_BaseConfig_T timer_base_configuration;
    timer_base_configuration.clockDivision = TMR_CLOCK_DIV_1;
    timer_base_configuration.division = 71;
    timer_base_configuration.period = 65000;
    timer_base_configuration.countMode = TMR_COUNTER_MODE_UP;
    timer_base_configuration.repetitionCounter = 0;
    TMR_ConfigTimeBase(TMR3,&timer_base_configuration);
    TMR_ICConfig_T timer_ic_configuration;
    timer_ic_configuration.channel = TMR_CHANNEL_1;
    timer_ic_configuration.filter = 0x00;
    timer_ic_configuration.polarity = TMR_IC_POLARITY_RISING;
    timer_ic_configuration.prescaler = TMR_IC_PSC_1;
    timer_ic_configuration.selection = TMR_IC_SELECTION_DIRECT_TI;
    TMR_ConfigPWM(TMR3,&timer_ic_configuration);
    TMR_SelectInputTrigger(TMR3,TMR_TRIGGER_SOURCE_TI1FP1);
    TMR_SelectSlaveMode(TMR3,TMR_SLAVE_MODE_RESET);
    TMR_EnableMasterSlaveMode(TMR3);
    TMR_Enable(TMR3);
    return true;
}

double PWMInput::getDuty(void){
    unsigned int period = TMR3->CC1;
    unsigned int pulse_width = TMR3->CC2;
    if ( period == 0 ) return 0;
    else return (double)pulse_width / (double)period;
}

void PWMInput::debugPrint(void){
    printf("PWM Input debug\r\n------------\r\n");
    printf("Duty:%.3lf\r\n\r\n",this->getDuty());
}

